<template>
    <div class="DepartmentIDs w-100">
        <el-cascader class="w-100" v-model="vModelData" :options="data" :props="{ multiple: props.multiple, checkStrictly: props.checkStrictly, emitPath: props.emitPath, disabled: props.disabledPropName, value: props.valueKey, label: props.labelKey }" :show-all-levels="false" collapse-tags clearable @change="onChange"></el-cascader>
    </div>
</template>

<script lang="ts" setup>
const props = defineProps({
    modelValue: {
        type: Array,
        default: [],
    },

    //搜索条件
    filter: {
        type: Object,
        default: {},
    },

    //是否自动加载数据
    isLoadingData: {
        type: Boolean,
        default: true,
    },

    //是否需要把数据转换成树型
    isConvertTreeData: {
        type: Boolean,
        default: true,
    },

    //是否多选
    multiple: {
        type: Boolean,
        default: true,
    },

    //是否严格遵守父子节点不互相关联
    checkStrictly: {
        type: Boolean,
        default: true,
    },

    //是否返回选择的全路径，设置为false就表示只返回选择的节点值
    emitPath: {
        type: Boolean,
        default: false,
    },

    //设置每一项禁用的属性名
    disabledPropName: {
        type: String,
        default: "isDisabled",
    },

    //指定选项的值为选项对象的某个属性值
    valueKey: {
        type: String,
        default: "departmentID",
    },

    //指定选项标签为选项对象的某个属性值
    labelKey: {
        type: String,
        default: "name",
    },
});

//定义数据
const data = ref();

const vModelData = ref();

//原始查询数据库得到，经过转成树型结构的数据
let originDepartmentTreeData = "";
//原始查询数据库得到，经过转成树型结构的数据，但所有项都被设置为了禁用
let allDisabledDepartmentTreeDatas = "";

watch(
    () => props.modelValue,
    (newVal, oldVal) => {
        if (props.isLoadingData == true) {
            if (!Gx.IsEmpty(newVal) && newVal.length > 0) {
                vModelData.value = newVal;

                //处理添加时引用此组件时会出现的问题，GetData的执行比watch要靠后，data.value在添加时会是空，这样就是引起在添加时，默认给的是不限，然后数据加载后，第2个数组中的数据也能选择了
                //这里就是判断处理，如果勾选的数据中有-1，而且还勾选了其它的项，则把-1这个给去掉
                let findIdx = newVal.findIndex((x) => x == -1);
                if (findIdx != -1 && newVal.length > 1) {
                    newVal.splice(findIdx, 1);
                }

                if (!Gx.IsEmpty(data.value)) {
                    if (newVal.length == 1 && newVal[0] == -1) {
                        //如果当前选择的只有一项，且这一项的id是-1，则认为选择是不限
                        data.value[0].isDisabled = false;
                        data.value[1] = Gx.DeserializeObject(allDisabledDepartmentTreeDatas);
                    } else {
                        data.value[0].isDisabled = true;
                        data.value[1] = Gx.DeserializeObject(originDepartmentTreeData);
                    }

                    data.value = Gx.DeepCopy(data.value);
                }
            } else {
                //如果什么都没有选择，则不限和数据都放开
                data.value[0].isDisabled = false;
                data.value[1] = Gx.DeserializeObject(originDepartmentTreeData);
                data.value = Gx.DeepCopy(data.value);
            }
        } else {
            if (!Gx.IsEmpty(newVal) && newVal.length > 0) {
                vModelData.value = newVal;
            }
        }
    },
    { immediate: true }
);

onMounted(() => {
    vModelData.value = props.modelValue;
    if (props.isLoadingData) {
        GetData();
    }
});

//获取数据
const GetData = () => {
    App.CallApi(Api.Department.GetAll(), {
        success: (res) => {
            //处理禁用作的数据，禁用与上否有权限刚好是相反的
            res.forEach((x) => {
                x.isDisabled = !x.hasPermission;
            });

            //记录原始数据
            let _resCopy = Gx.DeepCopy(res);
            originDepartmentTreeData = Gx.SerializeObject(Gx.List2Tree(_resCopy, "autoID")[0]);

            //再做一份所有项都禁用的数据，用于选择不限时，其它项都要禁用
            let _disabledResCopy = Gx.DeepCopy(res);
            _disabledResCopy.forEach((x) => {
                x.isDisabled = true;
            });
            allDisabledDepartmentTreeDatas = Gx.SerializeObject(Gx.List2Tree(_disabledResCopy, "autoID")[0]);

            //添加一个不限的项
            let _resArr = [{ departmentID: -1, name: "不限", parentID: -999 }];
            //添加其它部门数据
            _resArr.push(Gx.List2Tree(res, "autoID")[0]);

            //把数据转成树结构，并添加到数据集合中
            data.value = Gx.DeepCopy(_resArr);
        },
    });
};

//通过父组件设置数据
const SetData = (datas) => {
    data.value = Gx.DeepCopy(datas);
};

const onChange = (val) => {
    emit("update:modelValue", val);
    emit("change", val);
};

const emit = defineEmits(["update:modelValue", "change"]);
defineExpose({ SetData });
</script>
